import  torch
import  pandas as pd
import  numpy as np
import  matplotlib.pyplot as plt
from torch import nn
import  torch.nn.functional as F
data=pd.read_csv('HR.csv')

print(data.info)
print(data.part.unique())
print(data.salary.unique())
print(data.groupby(['salary','part']).size())

'''独热编码'''
print(pd.get_dummies(data.salary))
data=data.join(pd.get_dummies((data.salary)))
del data['salary']
data=data.join(pd.get_dummies((data.part)))
del data['part']
print("预测出来的准确率必须高于{}才有意义".format(11428/len(data)))

'''数据预处理'''
Y_data=data.left.values.reshape(-1,1)
Y=torch.from_numpy(Y_data).type(torch.float32)
X_data=data[[c for  c in data.columns if c!='left']].values
X=torch.from_numpy(X_data).type(torch.float32)

'''自定义创建模型'''
class Model(nn.Module):
    def __init__(self):
        super().__init__()
        self.liner_1=nn.Linear(20,64)
        self.liner_2=nn.Linear(64,64)
        self.liner_3=nn.Linear(64,1)

    def forward(self,input):
        x=F.relu(self.liner_1(input))
        x = F.relu(self.liner_2(x))
        x=F.sigmoid(self.liner_3(x))
        return x

'''学习效率'''
lr=0.0001

def get_model():
    model=Model()
    opt=torch.optim.Adam(model.parameters(),lr=lr)
    return model,opt

model,optimizer=get_model()

'''定义损失函数'''
loss_fn=nn.BCELoss()
batch=64
num_of_batch=len(data)//batch
epochs=100

'''使用dataset类进行重构'''
from torch.utils.data import  TensorDataset
from torch.utils.data import  DataLoader

HRdataset=TensorDataset(X,Y)
'''shuffle乱序处理'''
HRdataloader=DataLoader(HRdataset,batch_size=batch,shuffle=True)
'''不使用DataLoader的写法和DataLoader和TensorDateset都不使用的写法'''
# for epoch in range(epochs):
#     for i in range(num_of_batch):
#         x,y=HRdataset[i*batch:i*batch+batch]# start=i*batch
#         # end=start+batch
#         # x=X[start:end]
#         # y=Y[start:end]
#         y_pred=model(x)
#         loss=loss_fn(y_pred,y)
#         optimizer.zero_grad()
#         loss.backward()
#         optimizer.step()
#     with torch.no_grad():
#         print("epoch: ",epoch,"loss ",loss_fn(model(X),Y).data.item())

for epoch in range(epochs):
    for x,y in HRdataloader:
        y_pred=model(x)
        loss=loss_fn(y_pred,y)
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
    with torch.no_grad():
        print("epoch: ",epoch,"loss ",loss_fn(model(X),Y).data.item())



